<!--
 * Copyright 2022 The kubegems.io Authors
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *       http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. 
-->

<template>
  <v-card class="pa-4" flat>
    <div class="d-flex justify-space-between align-center">
      <ProjectSelect v-model="project" :tenant="tenant" />
      <Duration v-model="params.duration" />
    </div>

    <v-data-table
      class="px-2 mt-4"
      disable-sort
      :headers="headers"
      hide-default-footer
      item-key="value"
      :items="items"
      :items-per-page="params.size"
      :no-data-text="$root.$t('data.no_data')"
      :no-results-text="$root.$t('data.no_data')"
      :page.sync="params.page"
    >
      <template #[`item.labels`]="{ item, index }">
        <BaseCollapseChips :id="`o_label_${index}`" :chips="item.labels || {}" icon="mdi-label" single-line />
      </template>
      <template #[`item.alertLiving`]="{ item }">
        {{ (item.errorAlertCount || 0) + (item.criticalAlertCount || 0) }}
        <BaseTipChips
          v-if="item.criticalAlertCount || item.errorAlertCount"
          :chips="{ error: item.errorAlertCount, critical: item.criticalAlertCount }"
          :color="item.criticalAlertCount > 0 ? 'error' : 'warning'"
          icon="mdi-fire-alert"
          single-line
          small
        />
        <v-icon color="primary" small @click="toAlertDashboard"> mdi-open-in-new </v-icon>
      </template>
      <template #[`item.alertRuleCount`]="{ item }">
        {{ item.alertRuleCount }}
        <BaseTipChips :chips="item.alertResourceMap || {}" color="primary" icon="mdi-ruler" single-line small />
        <v-icon color="primary" small @click="toAlertRule(item)"> mdi-open-in-new </v-icon>
      </template>
      <template #[`item.monitorCollectorCount`]="{ item }">
        {{ item.monitorCollectorCount }}
        <v-icon color="primary" small @click="toMetrics(item)"> mdi-open-in-new </v-icon>
      </template>
      <template #[`item.status`]="{ item }">
        <StatusTag :item="item" :l="item.logging" :m="item.monitoring" :s="item.serviceMesh" />
      </template>
      <template #[`item.errorLogCount`]="{ item }">
        {{ beautyLogCount(item.errorLogCount || 0) }}
        <v-icon color="primary" small @click="showErrorLogRate(item)"> mdi-chart-line </v-icon>
      </template>
      <template #[`item.logRate`]="{ item }">
        {{ beautyLogRate(item.logRate || 0) }}
        <v-icon color="primary" small @click="showLogRate(item)"> mdi-chart-line </v-icon>
      </template>
      <template #[`item.eventCount`]="{ item }">
        {{ item.eventCount }}
        <v-icon color="primary" small @click="showEvents(item)"> mdi-chart-pie </v-icon>
      </template>
      <template #[`item.loggingCollectorCount`]="{ item }">
        {{ item.loggingCollectorCount }}
        <v-icon color="primary" small @click="toLogFlow(item)"> mdi-open-in-new </v-icon>
        <v-menu
          v-if="item.warning"
          bottom
          :close-delay="200"
          :close-on-content-click="false"
          max-width="200px"
          offset-y
          open-on-hover
          origin="top center"
          transition="scale-transition"
        >
          <template #activator="{ on }">
            <span class="kubegems__pointer" v-on="on">
              <v-icon color="error" small> mdi-alert-circle </v-icon>
            </span>
          </template>
          <v-card flat>
            <v-flex class="text-body-2 text-center primary white--text py-2">
              <v-icon color="white" left small> mdi-alert-circle </v-icon>
              <span>{{ $t('tip.error_info') }}</span>
            </v-flex>
            <v-list class="pa-0 kubegems__tip" dense>
              <v-list-item>
                <v-list-item-content>
                  <v-list-item class="float-left pa-0" two-line>
                    <v-list-item-content class="py-0">
                      <v-list-item-title> {{ $t('tip.error_info') }} </v-list-item-title>
                      <v-list-item-content class="text-caption kubegems__text kubegems__break-all">
                        {{ item.warning }}
                      </v-list-item-content>
                    </v-list-item-content>
                  </v-list-item>
                </v-list-item-content>
              </v-list-item>
            </v-list>
          </v-card>
        </v-menu>
      </template>
    </v-data-table>

    <BasePagination
      v-if="pageCount >= 1"
      v-model="params.page"
      :front-page="true"
      :page-count="pageCount"
      :size="params.size"
      @changepage="onPageIndexChange"
      @changesize="onPageSizeChange"
    />

    <K8sEvents ref="k8sEvents" :env="env" @clear="env = null" />
    <LogRateChart ref="logRateChart" :env="env" @clear="env = null" />
    <ErrorLogRateChart ref="errorLogRateChart" :env="env" @clear="env = null" />
  </v-card>
</template>

<script>
  import { getEnvironmentObservability } from '@kubegems/api/direct';
  import BaseSelect from '@kubegems/mixins/select';

  import messages from '../../i18n';
  import Duration from './Duration';
  import ErrorLogRateChart from './ErrorLogRateChart';
  import K8sEvents from './K8sEvents';
  import LogRateChart from './LogRateChart';
  import ProjectSelect from './ProjectSelect';
  import StatusTag from './StatusTag';

  export default {
    name: 'OverviewList',
    i18n: {
      messages: messages,
    },
    components: {
      Duration,
      ErrorLogRateChart,
      K8sEvents,
      LogRateChart,
      ProjectSelect,
      StatusTag,
    },
    mixins: [BaseSelect],
    props: {
      tenant: {
        type: Object,
        default: () => null,
      },
    },
    data() {
      return {
        params: {
          duration: '1h',
          page: 1,
          size: 10,
        },
        project: undefined,
        items: [],
        pageCount: 0,
        env: null,
      };
    },
    computed: {
      headers() {
        return [
          { text: this.$root.$t('resource.environment'), value: 'environmentName', align: 'start' },
          { text: this.$t('table.label'), value: 'labels', align: 'start' },
          { text: this.$t('table.status'), value: 'status', align: 'start', width: 250 },
          { text: this.$t('table.restart_count'), value: 'containerRestartTotal', align: 'start' },
          { text: this.$root.$t('resource.cpu'), value: 'cpu', align: 'start' },
          { text: this.$root.$t('resource.memory'), value: 'memory', align: 'start' },
          { text: this.$t('table.metrics_count'), value: 'monitorCollectorCount', align: 'end', width: 75 },
          { text: this.$t('table.alert_rule_count'), value: 'alertRuleCount', align: 'end', width: 75 },
          { text: this.$t('table.living_alert_count'), value: 'alertLiving', align: 'end', width: 75 },
          { text: this.$t('table.log_count'), value: 'loggingCollectorCount', align: 'end', width: 75 },
          { text: this.$t('table.error_log_count'), value: 'errorLogCount', align: 'end', width: 75 },
          { text: this.$t('table.log_rate'), value: 'logRate', align: 'end', width: 130 },
          { text: this.$t('table.event_count'), value: 'eventCount', align: 'end', width: 100 },
        ];
      },
    },
    watch: {
      project: {
        async handler() {
          if (this.project) {
            this.items = [];
            await this.m_select_projectEnvironmentSelectData(this.project);
            this.m_select_projectEnvironmentItems.forEach((env) => {
              this.items.push({ environmentName: env.environmentName });
              this.environmentObservability(env.value);
            });
          }
        },
        deep: true,
      },
      'params.duration': {
        handler() {
          this.items = [];
          this.m_select_projectEnvironmentItems.forEach((env) => {
            this.items.push({ environmentName: env.environmentName });
            this.environmentObservability(env.value);
          });
        },
      },
    },
    methods: {
      async environmentObservability(envId) {
        const data = await getEnvironmentObservability(envId, { duration: this.params.duration });
        const index = this.items.findIndex((e) => {
          return e.environmentName === data.environmentName;
        });
        if (index > -1) {
          this.$set(this.items, index, data);
        }
        this.pageCount = Math.ceil(this.items.length / this.params.size);
      },
      onPageSizeChange(size) {
        this.params.page = 1;
        this.params.size = size;
      },
      onPageIndexChange(page) {
        this.params.page = page;
      },
      showEvents(item) {
        this.env = item;
        this.$refs.k8sEvents.open();
      },
      showLogRate(item) {
        this.env = item;
        this.$refs.logRateChart.open();
      },
      showErrorLogRate(item) {
        this.env = item;
        this.$refs.errorLogRateChart.open();
      },
      beautyLogCount(count) {
        let result = parseFloat(count);
        const units = ['', 'k', 'm'];
        for (const index in units) {
          if (Math.abs(result) < 1000.0) {
            return `${result.toFixed(1)} ${units[index]}`;
          }
          result /= 1000.0;
        }
        return `${result.toFixed(1)} Yi`;
      },
      beautyLogRate(rate) {
        let result = rate ? parseInt(rate.replaceAll('/min', '')) : 0;
        result = `${this.beautyLogCount(result)} /min`;
        return result;
      },
      toMetrics(item) {
        this.$router.push({
          name: 'observe-monitor-config',
          query: {
            proj: item.projectName,
            env: item.environmentName,
            envid: item.environmentID,
            projid: item.projectID,
            cluster: item.clusterName,
            namespace: item.namespace,
          },
        });
      },
      toAlertRule(item) {
        this.$router.push({
          name: 'observe-monitor-config',
          query: {
            proj: item.projectName,
            env: item.environmentName,
            envid: item.environmentID,
            projid: item.projectID,
            cluster: item.clusterName,
            namespace: item.namespace,
            tab: 'prometheusrule',
          },
        });
      },
      toLogFlow(item) {
        this.$router.push({
          name: 'log-config',
          query: {
            proj: item.projectName,
            env: item.environmentName,
            envid: item.environmentID,
            projid: item.projectID,
            cluster: item.clusterName,
            namespace: item.namespace,
          },
        });
      },
      toAlertDashboard() {
        this.$router.push({
          name: 'observe-monitor-overview',
        });
      },
    },
  };
</script>
